package com.smasher.widget.base

import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import java.util.Arrays

/**
 * Constructor
 *
 * @param context            The current context.
 * @param resource           The resource ID for a layout file containing a layout to use when
 * instantiating views.
 * @param textViewResourceId The id of the TextView within the layout resource to be populated
 * @param objects            The objects to represent in the ListView.
 */
abstract class BaseSpinnerAdapter<T> @JvmOverloads constructor(
    context: Context,
    resource: Int,
    textViewResourceId: Int = 0,
    objects: List<T> = ArrayList()
) : ArrayAdapter<T>(context, resource, textViewResourceId, objects) {

    private var mFieldId = 0
    private val mResource: Int
    private var mDropDownResource: Int


    init {
        mFieldId = textViewResourceId
        mDropDownResource = resource
        mResource = resource
    }


    /**
     * Constructor. This constructor will result in the underlying data collection being
     * immutable, so methods such as [.clear] will throw an exception.
     *
     * @param context  The current context.
     * @param resource The resource ID for a layout file containing a TextView to use when
     * instantiating views.
     * @param objects  The objects to represent in the ListView.
     */
    constructor(context: Context, resource: Int, objects: Array<T>) : this(
        context,
        resource,
        0,
        listOf<T>(*objects)
    )

    /**
     * Constructor. This constructor will result in the underlying data collection being
     * immutable, so methods such as [.clear] will throw an exception.
     *
     * @param context            The current context.
     * @param resource           The resource ID for a layout file containing a layout to use when
     * instantiating views.
     * @param textViewResourceId The id of the TextView within the layout resource to be populated
     * @param objects            The objects to represent in the ListView.
     */
    constructor(context: Context, resource: Int, textViewResourceId: Int, objects: Array<T>) : this(
        context,
        resource,
        textViewResourceId,
        Arrays.asList<T>(*objects)
    )

    /**
     * Constructor
     *
     * @param context  The current context.
     * @param resource The resource ID for a layout file containing a TextView to use when
     * instantiating views.
     * @param objects  The objects to represent in the ListView.
     */
    constructor(context: Context, resource: Int, objects: List<T>) : this(
        context,
        resource,
        0,
        objects
    )


    /**
     *
     * Sets the layout resource to create the drop down views.
     *
     * @param resource the layout resource defining the drop down views
     * @see .getDropDownView
     */
    override fun setDropDownViewResource(resource: Int) {
        super.setDropDownViewResource(resource)
        mDropDownResource = resource
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val inflater = LayoutInflater.from(context)
        return createViewFromResource(inflater, position, convertView, parent, mResource)
    }


    override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
        val inflater = LayoutInflater.from(context)
        return createViewFromResource(inflater, position, convertView, parent, mDropDownResource)
    }


    private fun createViewFromResource(
        inflater: LayoutInflater,
        position: Int,
        convertView: View?,
        parent: ViewGroup,
        resource: Int
    ): View {
        val text: TextView
        val view = convertView ?: inflater.inflate(resource, parent, false)

        try {
            if (mFieldId == 0) {
                //  If no custom field is assigned, assume the whole resource is a TextView
                text = view as TextView
            } else {
                //  Otherwise, find the TextView field within the layout
                text = view.findViewById(mFieldId)
                if (text == null) {
                    throw RuntimeException(
                        ("Failed to find view with ID "
                                + context.resources.getResourceName(mFieldId)
                                + " in item layout")
                    )
                }
            }
        } catch (e: ClassCastException) {
            Log.e(TAG, "ArrayAdapter You must supply a resource ID for a TextView", e)
            throw IllegalStateException(
                "ArrayAdapter requires the resource ID to be a TextView", e
            )
        }

        val item = getItem(position)

        // 修改此处类型检查
        text.text = when (item) {
            is CharSequence -> item
            else -> getShowText(item) // 添加空安全处理
        }

        return view
    }

    protected abstract fun getShowText(item: T?): String

    companion object {
        const val TAG: String = "BaseSpinnerAdapter"
    }
}
